package fons.navigator.ui.windows;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Window;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JLabel;
import javax.swing.SwingWorker;
import javax.swing.event.InternalFrameAdapter;
import javax.swing.event.InternalFrameEvent;

import fons.navigator.NavigatorMain;
import fons.navigator.ui.NavigatorMainFrame;
import fons.navigator.util.SwingUtils;
import fons.navigator.util.piccolo.PBoxLayoutNode;
import fons.navigator.views.NavigatorViewCreator;
import fons.navigator.views.View;
import fons.navigator.views.ViewConfig;
import fons.navigator.views.VisualCanvas;

public class ViewWindow extends JInternalFrame {
	private static final long serialVersionUID = 1L;
	
	private static final ImageIcon LOADING_ICON = NavigatorMain.createImageIcon("ui/resources/fons.png");
	private static final Font LOADING_TEXT_FONT = new Font("Sans Serif", Font.PLAIN, 13);
	
	public ViewWindow(final NavigatorViewCreator viewDefinition) {
		super("", true, true, true, true);
		setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

		final JLabel loadingLabel = new JLabel();
		loadingLabel.setFont(LOADING_TEXT_FONT);
		loadingLabel.setHorizontalAlignment(JLabel.LEFT);
		loadingLabel.setIcon(LOADING_ICON);
		loadingLabel.setText("Lade...");
		add(loadingLabel);		
		setBackground(Color.white);

		SwingWorker<View, Object> worker = new SwingWorker<View, Object>() {
			final ViewConfig config = getApp().getActiveContext().getProperty("ViewConfig", ViewConfig.class);

			@Override
			public View doInBackground() throws Exception {
				ViewWindow.this.setVisible(true);
				adjustWindowSize(ViewWindow.this);
				final View view = viewDefinition.getView(config);
				getApp().setActiveView(view.getViewModel());
				return view;
			}

			private void adjustWindowSize(final Container parent) {
				String size = config.getString(ViewConfig.PROP_WINDOW_SIZE);
				if (size != null) {
					Matcher m = Pattern.compile("(\\d+)x(\\d+)").matcher(size);
					if (m.matches()) {
						Dimension dim = new Dimension(Integer.parseInt(m.group(1)), Integer.parseInt(m.group(2)));

						JInternalFrame iframe = SwingUtils.getInternalFrameFor(parent);
						if (iframe != null) {
							iframe.setSize(dim);
						} else {
							Window win = SwingUtils.getWindowFor(parent);
							if (win != null) {
								win.setSize(dim);
							}
						}
					}
				}
			}

			@Override
			protected void done() {
				boolean isViewEmpty = true;
				try {

					View view = get();
					if (view != null) {
						VisualCanvas canvas = view.getVisualCanvas();
						if (canvas != null) {
							canvas.setInternalFrame(ViewWindow.this);
							ViewWindow.this.add(canvas, BorderLayout.CENTER);
							isViewEmpty = false;

							JInternalFrame iframe = SwingUtils.getInternalFrameFor(ViewWindow.this);

							if (iframe != null) {
								iframe.setTitle(view.getName());

							} else {
								Window w = SwingUtils.getWindowFor(ViewWindow.this);
								w.addWindowListener(canvas.getWindowListener());
								w.setName(view.getName());
							}

							final JComponent controls = view.getControls();
							initControls(ViewWindow.this, canvas, controls, config);
							canvas.repaint();

							NavigatorMain.getMainFrame().setStatusMessage("Bereit");
						}
					}

				} catch (Exception ex) {
					ex.printStackTrace();
					isViewEmpty = true;

				} finally {
					try {
						ViewWindow.this.remove(loadingLabel);
						if (isViewEmpty) {
							ViewWindow.this.add(new JLabel("No view", JLabel.CENTER), BorderLayout.CENTER);
						}
						ViewWindow.this.validate();

					} catch (Exception ex) {
						// ignore
					}
				}
			}
		};
		worker.execute();

		final JDesktopPane desktopPane = getApp().getDesktopPane();
		desktopPane.add(ViewWindow.this);
		ViewWindow.this.setPreferredSize(new Dimension(800, 600));
		ViewWindow.this.pack();

		final int offset = desktopPane.getAllFrames().length * 16;
		ViewWindow.this.setLocation(offset, offset);
		ViewWindow.this.addInternalFrameListener(new InternalFrameAdapter() {
			@Override
			public void internalFrameActivated(InternalFrameEvent e) {
				getApp().setActiveFrame(e.getInternalFrame());
			}

			@Override
			public void internalFrameDeactivated(InternalFrameEvent e) {
			}

			@Override
			public void internalFrameOpened(InternalFrameEvent e) {
			}

			@Override
			public void internalFrameClosed(InternalFrameEvent e) {
			}
		});

		ViewWindow.this.setVisible(true);
	}
	
	private NavigatorMainFrame getApp() {
		return NavigatorMain.getMainFrame();
	}
	
	private static void initControls(final Container parent, VisualCanvas canvas,
			final JComponent controls, ViewConfig config) {
		PBoxLayoutNode buttonPanel = canvas.getSettingButtonsPanel();
		buttonPanel.removeAllChildren();

		parent.add(controls, BorderLayout.SOUTH);
	}
}